package com.hermes.comics.data;

import android.app.Activity;

import android.text.TextUtils;

import android.util.Log;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Catalog {

  private final Activity activity;

  private Map<String, Serie> seriesMap;

  private static Catalog instance;

  public static Catalog init(Activity activity) {
    if (instance == null) {
      instance = new Catalog(activity);
    }
    return instance;
  }

  public static Catalog getInstance() {
    return instance;
  }

  private Catalog(Activity activity) {
    this.activity = activity;
    this.seriesMap = new HashMap<String, Serie>();
  }

  public List<Serie> getAllSeries() {
    List<Serie> series = new ArrayList<Serie>(seriesMap.values());
    Collections.sort(series, Constants.SERIE_COMPARATOR);
    return series;
  }

  public Serie getSerie(Issue issue) {
    return getSerie(IssueTag.SERIE_KEY.value(issue));
  }

  public Serie getSerie(String key) {
    return seriesMap.get(key);
  }

  public void commit(Item item) {
    if (item.getClass().equals(Serie.class)) {
      commit((Serie) item);
    } else if (item.getClass().equals(Issue.class)) {
      commit((Issue) item);
    }
  }

  public void commit(Serie serie) {
    if (serie == null) return;

    String key = SerieTag.KEY.value(serie);
    seriesMap.remove(key);
    seriesMap.put(key, serie);

    appendCommit(Constants.DB_PATH + Constants.SERIES_FILENAME, serie);
  }

  public void commit(Issue issue) {
    if (issue == null) return;

    getSerie(issue).addIssue(issue);

    appendCommit(Constants.DB_PATH + Constants.ISSUES_FILENAME, issue);
  }

  private void appendCommit(String filename, Item item) {
    try {
      FileWriter f = new FileWriter(filename, true);
      f.write(TextUtils.join("\t", item.row()) + "\n");
      f.flush();
      f.close();
    } catch (IOException e) {
      System.out.println("-----------------> Could not append to " + filename);
    }
  }

  private boolean LoadSeries(String filename) {
    File file = new File(filename);
    String line = "";
    try {
      BufferedReader buffer = new BufferedReader(new FileReader(file));
      line = buffer.readLine();
      while ((line = buffer.readLine()) != null) {
        String[] fields = line.split("\t");
        Serie serie = new Serie();
        for (SerieTag serieTag : SerieTag.values()) {
          if (serieTag.index() >= fields.length) continue;

          serie.setTag(serieTag, fields[serieTag.index()]);
        }
        if ("".equals(SerieTag.LANGUAGE.value(serie))) {
          serie.setTag(SerieTag.LANGUAGE, "pt");
        }
        seriesMap.put(serie.getTagValue(SerieTag.KEY), serie);
      }
      return true;
    } catch (IOException e) {
      System.out.println("-----------------> Could not open/parse series file " + filename);
      System.out.println("Line with problem: (" + line + ")");
      return false;
    }
  }

  private boolean LoadIssues(String filename) {
    File file = new File(filename);
    String line = "";
    try {
      BufferedReader buffer = new BufferedReader(new FileReader(file));
      line = buffer.readLine();
      while ((line = buffer.readLine()) != null) {
        String[] fields = line.split("\t");
        Issue issue = new Issue();
        for (IssueTag issueTag : IssueTag.values()) {
          if (issueTag.index() >= fields.length) continue;

          String value = fields[issueTag.index()];
          if (issueTag == IssueTag.URL) {
            value = value.replaceAll("\\+", ""); 
          }
          issue.setTag(issueTag, value);
        }
        Serie serie = seriesMap.get(issue.getTagValue(IssueTag.SERIE_KEY));
        if (serie != null) {
          serie.addIssue(issue);
        }
      }
      return true;
    } catch (IOException e) {
      System.out.println("--------------------> Could not open/parse issues file = " + filename);
      System.out.println("Line with problem: (" + line + ")");
      System.out.println(e.toString());
      return false;
    }
  }

  public boolean load() {
    seriesMap.clear();
    if (LoadSeries(Constants.DB_PATH + Constants.SERIES_FILENAME) &&
        LoadIssues(Constants.DB_PATH + Constants.ISSUES_FILENAME)) {
      return true;
    }
    return false;
  }
}
